﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

/*
class Calculator
{
public:
	void setV1(int v)
	{
		this->val1 = v;
	}
	void setV2(int v)
	{
		this->val2 = v;
	}

	int getResult(string oper)
	{
		if (oper == "+")
		{
			return val1 + val2;
		}
		else if (oper == "-")
		{
			return val1 - val2;
		}
	}

private:
	int val1;
	int val2;
};
void testCalculator()
{
	Calculator cal;
	cal.setV1(10);
	cal.setV2(10);
	cout << cal.getResult("+") << endl;//20
	cout << cal.getResult("-") << endl;//0
}*/
//1.真正的开发中，有个开发原则：开闭原则！对扩展开放，对修改关闭；
//2.利用多态实现计算器；
class AbstractCalculator
{
public:
	void setV1(int v)
	{
		this->val1 = v;
	}
	void setV2(int v)
	{
		this->val2 = v;
	}

	//5.虚函数改成纯虚函数；如果父类中有纯虚函数，子类继承父类，就必须要实现纯虚函数；
	//virtual int getResult() { return 0; };
	//7.如果父类中有纯虚函数，则这个父类就无法实例化对象了；
		//这个类有了纯虚函数，通常又成为抽象类；
	virtual int getResult() = 0;

	//private:
public:
	int val1;
	int val2;
};
//3.加法计算器；
class PlusCalculator :public AbstractCalculator
{
public:
	virtual int getResult()
	{
		return val1 + val2;
	}
};
class SubCalculator :public AbstractCalculator
{
public:
	virtual int getResult()
	{
		return val1 - val2;
	}
};
class MuxCalculator :public AbstractCalculator
{
public:
	virtual int getResult()
	{
		return val1 * val2;
	}
};
//6.如果父类中有纯虚函数，子类继承父类，就必须要实现纯虚函数；
class RandomClass :public AbstractCalculator
{
public:
	virtual int getResult()
	{
		return 0;
	}
};
void testAbstractCalculator()
{
	AbstractCalculator* abc;
	//4.加法计算器，发生多态；
	abc = new PlusCalculator;

	abc->setV1(10);
	abc->setV2(20);
	cout << abc->getResult() << endl;//30
	delete abc;

	abc = new SubCalculator;

	abc->setV1(10);
	abc->setV2(20);
	cout << abc->getResult() << endl;//-10
	delete abc;

	abc = new MuxCalculator;

	abc->setV1(10);
	abc->setV2(20);
	cout << abc->getResult() << endl;//200

	RandomClass rs;

	//7.如果父类中有纯虚函数，则这个父类就无法实例化对象了；
	//AbstractCalculator cal;
	//AbstractCalculator* calculator = new AbstractCalculator;
}

//main294：多态案例实现计算器
int main294()
{
	//testCalculator();
	testAbstractCalculator();

	system("pause");
	return EXIT_SUCCESS;
}